#include <iostream>
#include <string>
#include <vector>

#include <cstdlib>
#include <cstring>
#include <unistd.h>
#include <pthread.h>

#define NUM 5
int tickets = 2500;
pthread_mutex_t lock;
pthread_cond_t cond;

void *getTickets(void *args)
{
    std::string name = static_cast<const char *>(args);
    while (true)
    {
        // 1.加锁
        pthread_mutex_lock(&lock);

        // 2.在条件变量下等待
        pthread_cond_wait(&cond, &lock);

        // 3.访问临界资源
        if (tickets > 0)
            std::cout << "线程" << name << " 获取票号[" << tickets-- << ']' << std::endl;
        else
            break;
        // 4.解锁
        pthread_mutex_unlock(&lock);
    }
    return nullptr;
}

int main()
{
    // 0.初始化锁和线程
    pthread_mutex_init(&lock, nullptr);
    pthread_cond_init(&cond, nullptr);

    // 1.创建一批线程，使用vector保存
    std::vector<pthread_t> tids(NUM);
    for (int i = 0; i < 5; i++)
    {
        char buffer[64];
        snprintf(buffer, sizeof(buffer), "thread - %d", i);
        pthread_create(&tids[i], nullptr, getTickets, (void *)buffer);
    }

    // 2.主线程每隔一秒唤醒一个线程
    while (true)
    {
        // sleep(1);
        // std::cout << "主线程唤醒一个线程" << std::endl;
        pthread_cond_signal(&cond);
    }

    // 3.主线程等待所有的线程
    for (int i = 0; i < NUM; i++)
    {
        sleep(1);
        pthread_join(tids[i], nullptr);
    }

    // 4.销毁锁和条件变量
    pthread_mutex_destroy(&lock);
    pthread_cond_destroy(&cond);

    return 0;
}
